package web

import (
	"errors"
	"github.com/gin-contrib/sessions"
	"github.com/gin-gonic/gin"
	"internal/internal/domain"
	"internal/internal/middleware"
	"internal/internal/service"
	"net/http"
)

type UserHandler struct {
	svc *service.UserService
}

// NewUserHandler 构造函数注入(依赖注入)
func NewUserHandler(svc *service.UserService) *UserHandler {
	return &UserHandler{
		svc: svc,
	}
}

// RegisterRoutes 用户操作路由
func (c *UserHandler) RegisterRoutes(server *gin.Engine) {

	server.POST("/users/signup", c.Signup)
	server.POST("/users/login", c.Login)

	authGroup := server.Group("/")
	authGroup.Use(middleware.AuthRequired())
	{
		authGroup.POST("/users/edit", c.Edit)
		authGroup.POST("/users/profile", c.Profile)
		authGroup.POST("/users/logout", c.Logout)
	}
}

// Signup 用户注册接口
func (c *UserHandler) Signup(context *gin.Context) {
	// 1.获取参数
	type SignUpReq struct {
		Username        string `json:"username"`
		Password        string `json:"password"`
		ConfirmPassword string `json:"confirmPassword"`
	}

	var req SignUpReq
	var err error
	// 调用 Bind 方法，会自动绑定context中的json对应格式
	if err = context.Bind(&req); err != nil {
		context.String(http.StatusOK, "系统异常")
		return
	}

	// 2.校验参数
	if req.ConfirmPassword != req.ConfirmPassword {
		context.String(http.StatusOK, "两次密码不一致")
		return
	}

	// 调用 service 部分
	err = c.svc.Signup(context, domain.User{
		Username: req.Username,
		Password: req.Password,
	})
	if err != nil {
		if errors.Is(err, service.ErrUserDuplicateEmail) {
			context.String(http.StatusOK, "用户名已存在")
			return
		}
		context.String(http.StatusOK, "系统异常")
		return
	}

	context.String(http.StatusOK, "注册成功")
}

func (c *UserHandler) Login(context *gin.Context) {

	type SignUpReq struct {
		Username string `json:"username"`
		Password string `json:"password"`
	}

	var req SignUpReq
	var err error
	// 调用 Bind 方法，会自动绑定context中的json对应格式
	if err = context.Bind(&req); err != nil {
		return
	}

	u, err := c.svc.Login(context, domain.User{
		Username: req.Username,
		Password: req.Password,
	})
	if err != nil {
		context.String(http.StatusBadRequest, "登录失败")
		return
	}

	// 登录成功，设置Session
	session := sessions.Default(context)
	session.Set("userId", u.Id) // 将用户名存入Session

	if err = session.Save(); err != nil {
		context.String(http.StatusInternalServerError, "保存Session失败")
		return
	}
	context.String(http.StatusOK, "登录成功")
}

func (c *UserHandler) Logout(ctx *gin.Context) {
	session := sessions.Default(ctx)
	session.Delete("user")
	if err := session.Save(); err != nil {
		ctx.String(http.StatusInternalServerError, "登出失败")
	}
	ctx.String(http.StatusOK, "登出成功")
}

func (c *UserHandler) Edit(context *gin.Context) {
	context.String(http.StatusOK, "设置成功")
}

func (c *UserHandler) Profile(context *gin.Context) {
	//context.String(http.StatusOK, "个人信息界面")
	session := sessions.Default(context)
	user := session.Get("user")
	context.JSON(http.StatusOK, gin.H{
		"username": user,
		"message":  "个人信息界面",
	})
}
